package com.example.excelimport.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;

@Component
@Slf4j
public class FileUtil {

    /**
     * 创建目录（如果不存在）
     */
    public static void createDirectoryIfNotExists(String dirPath) {
        try {
            Path path = Paths.get(dirPath);
            if (!Files.exists(path)) {
                Files.createDirectories(path);
                log.info("目录创建成功: {}", dirPath);
            }
        } catch (IOException e) {
            log.error("创建目录失败: {}", dirPath, e);
            throw new RuntimeException("目录创建失败: " + dirPath, e);
        }
    }

    /**
     * 创建文件所在目录
     */
    public static void createFileDirectory(String filePath) {
        try {
            Path path = Paths.get(filePath);
            Path parentDir = path.getParent();
            if (parentDir != null && !Files.exists(parentDir)) {
                Files.createDirectories(parentDir);
            }
        } catch (IOException e) {
            log.error("创建文件目录失败: {}", filePath, e);
            throw new RuntimeException("文件目录创建失败: " + filePath, e);
        }
    }

    /**
     * 检查文件是否存在
     */
    public static boolean fileExists(String filePath) {
        return Files.exists(Paths.get(filePath));
    }

    /**
     * 删除文件
     */
    public static void deleteFile(String filePath) {
        try {
            Files.deleteIfExists(Paths.get(filePath));
        } catch (IOException e) {
            log.error("删除文件失败: {}", filePath, e);
        }
    }

    /**
     * 清理目录中的指定类型文件
     */
    public static long clearDirectory(String dirPath, String fileExtension) {
        long deletedCount = 0;

        try {
            Path directory = Paths.get(dirPath);
            if (!Files.exists(directory)) {
                log.warn("目录不存在: {}", dirPath);
                return 0;
            }

            try (Stream<Path> paths = Files.walk(directory)) {
                deletedCount = paths
                        .filter(Files::isRegularFile)
                        .filter(path -> fileExtension == null || path.toString().endsWith(fileExtension))
                        .map(path -> {
                            try {
                                Files.delete(path);
                                log.debug("删除文件: {}", path);
                                return 1;
                            } catch (IOException e) {
                                log.warn("删除文件失败: {}", path, e);
                                return 0;
                            }
                        })
                        .count();
            }

            log.info("清理目录 {} 完成，共删除 {} 个文件", dirPath, deletedCount);

        } catch (IOException e) {
            log.error("清理目录失败: {}", dirPath, e);
            throw new RuntimeException("清理目录失败: " + dirPath, e);
        }

        return deletedCount;
    }

    /**
     * 获取目录大小
     */
    public static String getDirectorySize(String dirPath) {
        try {
            Path directory = Paths.get(dirPath);
            if (!Files.exists(directory)) {
                return "0 B";
            }

            long size = Files.walk(directory)
                    .filter(Files::isRegularFile)
                    .mapToLong(path -> {
                        try {
                            return Files.size(path);
                        } catch (IOException e) {
                            return 0;
                        }
                    })
                    .sum();

            return formatFileSize(size);

        } catch (IOException e) {
            log.error("获取目录大小失败: {}", dirPath, e);
            return "未知";
        }
    }

    private static String formatFileSize(long size) {
        if (size < 1024) {
            return size + " B";
        } else if (size < 1024 * 1024) {
            return String.format("%.2f KB", size / 1024.0);
        } else if (size < 1024 * 1024 * 1024) {
            return String.format("%.2f MB", size / (1024.0 * 1024.0));
        } else {
            return String.format("%.2f GB", size / (1024.0 * 1024.0 * 1024.0));
        }
    }
}